/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 中科软支付平台
 * 创建日期 : 2017年1月3日
 * 修改历史 : 
 *     1. [2017年1月3日]创建文件 by liuyujia
 */
package com.sinosoft.sinopay.web.weixinpay.web.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_DEALTYPE;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_REPORTTYPE;
import com.sinosoft.sinocloud.common.config.ENUM_REPORTLOG_STATE;
import com.sinosoft.sinocloud.common.dto.ReportLogDTO;
import com.sinosoft.sinocloud.platform.base.SinoBaseController;
import com.sinosoft.sinocloud.platform.common.exception.biz.BizDataErrException;
import com.sinosoft.sinocloud.platform.common.exception.biz.SinoBizException;
import com.sinosoft.sinocloud.platform.common.exception.system.SinoSystemException;
import com.sinosoft.sinocloud.platform.common.util.DateUtil;
import com.sinosoft.sinocloud.platform.common.util.SecurityUtil;
import com.sinosoft.sinopay.api.common.dto.pay.PaymentInfoDetailDTO;
import com.sinosoft.sinopay.api.common.dto.query.PayInfoQryParam;
import com.sinosoft.sinopay.merchants.dto.MerchantSignInfo;
import com.sinosoft.sinopay.merchants.facade.MerchantInfoFacadeService;
import com.sinosoft.sinopay.paytrade.facade.PaymentTradeQueryFacadeService;
import com.sinosoft.sinopay.web.util.AmountTransUtil;
import com.sinosoft.sinopay.web.util.WechatSignUtil;
import com.sinosoft.sinopay.web.weixinpay.biz.config.ENUM_RETURN_MSG;
import com.sinosoft.sinopay.web.weixinpay.biz.config.QueryPaymentContants;
import com.sinosoft.sinopay.web.weixinpay.biz.service.SingleRecordQueryService;
import com.sinosoft.sinopay.web.weixinpay.dto.PayInfoQryRequestDTO;
import com.sinosoft.sinopay.web.weixinpay.dto.PayInfoQryResponseDTO;

/**  
 * 【交易查询 服务】
 * @author dengcanyang
 * @date 2017年1月7日 下午20:42:04 
 * @version V1.0  
 */
@Controller
@RequestMapping("/sinopay/payResultQuery")
public class PayResultQryController extends SinoBaseController{
	@Autowired
    private SingleRecordQueryService singleRecordQueryService;
    @Autowired
    PaymentTradeQueryFacadeService paymentTradeQueryFacadeService;
    @Autowired
    MerchantInfoFacadeService merchantInfoFacadeService;
    
	@RequestMapping(value = "queryRequest.do",method = RequestMethod.POST)
	public void getPayResult(HttpServletRequest request,HttpServletResponse response){
		logger.info("查询请求开始"); 
		//1.接收请求参数
		String tPayData = request.getParameter("query_data");
    	String tSignMsg = request.getParameter("sign_msg");
    	logger.info("查询请求参数："+tPayData+"查询请求签名："+tSignMsg);
    	String tRequestIp = getRemortIP(request);
    	ReportLogDTO tReportLogDTO = new ReportLogDTO();//定义日志对象
        //返回信息定义
        PayInfoQryResponseDTO tPayInfoQryResponseDTO = new PayInfoQryResponseDTO();
		try{
//			response.setCharacterEncoding("utf-8");
			//2.请求信息解密
		    logger.info("----请求信息解密----");
			String tDecodeData = SecurityUtil.aesDecrypt(tPayData, QueryPaymentContants.REPORT_ENCRY_KEY);
			logger.info("查询请求信息明文："+tDecodeData);
			//3.解析报文
			PayInfoQryRequestDTO  tPayInfoQryRequestDTO = JSON.parseObject(tDecodeData, PayInfoQryRequestDTO.class);
            //4 验证签名合法性
			logger.info("----开始验证签名合法性----");
            String tMerchantCode = tPayInfoQryRequestDTO.getMerchantCode();
            singleRecordQueryService.checkMerchantSignValid(tMerchantCode, tPayInfoQryRequestDTO, tSignMsg);
            //5.生成报文日志对象
            logger.info("----日志信息----");
            tReportLogDTO.setSourceCode(tPayInfoQryRequestDTO.getMerchantCode());
            tReportLogDTO.setRequestIp(tRequestIp);
            tReportLogDTO.setRequestXml(tDecodeData);
            tReportLogDTO.setReportType(ENUM_REPORTLOG_REPORTTYPE.RECEIVE.code());
            tReportLogDTO.setSerialNo(tPayInfoQryRequestDTO.getSerialNo());
            tReportLogDTO.setOrderBizNo(tPayInfoQryRequestDTO.getBizNo());
            tReportLogDTO.setDealType(ENUM_REPORTLOG_DEALTYPE.SYNC_DEAL.code());
            tReportLogDTO.setCallbackUrl("");
            //查询条件
            PayInfoQryParam tPayInfoQryParam = new PayInfoQryParam();
            if (!"".equals(tPayInfoQryRequestDTO.getPayNo())&&null!=tPayInfoQryRequestDTO.getPayNo()) {
            	logger.info("查询条件，payNo="+tPayInfoQryRequestDTO.getPayNo());
                tPayInfoQryParam.setPayNo(tPayInfoQryRequestDTO.getPayNo());
            }
            if (!"".equals(tPayInfoQryRequestDTO.getMerchantCode())&&null!=tPayInfoQryRequestDTO.getMerchantCode()&&!"QUERY".equals(tPayInfoQryRequestDTO.getMerchantCode())) {
            	logger.info("查询条件，merchantCode="+tPayInfoQryRequestDTO.getMerchantCode());
                tPayInfoQryParam.setMerchantCode(tPayInfoQryRequestDTO.getMerchantCode());
            }
            if (!"".equals(tPayInfoQryRequestDTO.getPayType())&&null!=tPayInfoQryRequestDTO.getPayType()) {
            	logger.info("查询条件，PayType="+tPayInfoQryRequestDTO.getPayType());
                tPayInfoQryParam.setPayType(tPayInfoQryRequestDTO.getPayType());
            }
            
            if (!"".equals(tPayInfoQryRequestDTO.getBizType())&&null!=tPayInfoQryRequestDTO.getBizType()) {
            	logger.info("查询条件，BizType="+tPayInfoQryRequestDTO.getBizType());
                tPayInfoQryParam.setBizType(tPayInfoQryRequestDTO.getBizType());
            }
            logger.info("----查询交易开始----");
            List<PaymentInfoDetailDTO> tPaymentInfoDetailList= paymentTradeQueryFacadeService.queryPaymentDetailsByParam(tPayInfoQryParam);
            if (tPaymentInfoDetailList.size()>0) {
            	logger.info("----查询结果存在----");
                //封装返回参数
                for (int i = 0; i < tPaymentInfoDetailList.size(); i++) {
                    tPayInfoQryResponseDTO.setMerchantCode(tPaymentInfoDetailList.get(i).getMerchantCode());
                    tPayInfoQryResponseDTO.setBizNo(tPaymentInfoDetailList.get(i).getBizNo());
                    tPayInfoQryResponseDTO.setPayAmount(tPaymentInfoDetailList.get(i).getPayAmount());
                    if (tPaymentInfoDetailList.get(i).getCurrency().equals("")||tPaymentInfoDetailList.get(i).getCurrency()==null) {
                        tPaymentInfoDetailList.get(i).setCurrency("CNY");
                    }
                    tPayInfoQryResponseDTO.setCurrency(tPaymentInfoDetailList.get(i).getCurrency());
                    if (tPaymentInfoDetailList.get(i).getPayType().equals("")||tPaymentInfoDetailList.get(i).getPayType()==null) {
                        tPaymentInfoDetailList.get(i).setPayType("75");
                    }
                    tPayInfoQryResponseDTO.setPayType(tPaymentInfoDetailList.get(i).getPayType());
                    //tPaymentInfoDetailList.get(i).getPayDate() Date格式 转换
                   // String dataPay = DateUtil.transDateFormat(tPaymentInfoDetailList.get(i).getPayDate(), "yyyy-MM-dd HH:mm:ss").toString();
//                    SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//24小时制  
//                    String LgTime = sdformat.format(tPaymentInfoDetailList.get(i).getPayDate()); 
                    String LgTime=DateUtil.getDateStr(tPaymentInfoDetailList.get(i).getPayDate(),"yyyy-MM-dd HH:mm:ss");
                    tPayInfoQryResponseDTO.setPayDate(LgTime);
                    tPayInfoQryResponseDTO.setReturnCode(ENUM_RETURN_MSG.SUCC_INFO.code());
                    tPayInfoQryResponseDTO.setReturnMsg(ENUM_RETURN_MSG.SUCC_INFO.desc());
                }
                tPayInfoQryResponseDTO.setPassCode(ENUM_RETURN_MSG.SUCC_INFO.code());
                tPayInfoQryResponseDTO.setPassMsg(ENUM_RETURN_MSG.SUCC_INFO.desc());
            }else {
                tPayInfoQryResponseDTO.setPassCode("111111");
                tPayInfoQryResponseDTO.setPassMsg("查询交易信息返回结果为空，请重新进行查询");
            }  
		}catch(BizDataErrException ex){
            logger.error(ex.getStackTrace());
            tPayInfoQryResponseDTO.setPassCode(ENUM_RETURN_MSG.FAIL_INFO.code());
            tPayInfoQryResponseDTO.setPassMsg(ENUM_RETURN_MSG.FAIL_INFO.desc());
            tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
            tReportLogDTO.setDescription(ex.getMessage());
        }catch(SinoBizException ex){
            logger.error(ex.getStackTrace());
            tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
            tReportLogDTO.setDescription(ex.getMessage());
            tPayInfoQryResponseDTO.setPassCode(ENUM_RETURN_MSG.FAIL_INFO.code());
            tPayInfoQryResponseDTO.setPassMsg(ENUM_RETURN_MSG.FAIL_INFO.desc());
        }catch(SinoSystemException ex){
            logger.error(ex.getStackTrace());
            tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
            tReportLogDTO.setDescription(ex.getMessage());
            tPayInfoQryResponseDTO.setPassCode(ENUM_RETURN_MSG.FAIL_INFO.code());
            tPayInfoQryResponseDTO.setPassMsg("系统异常，请联系管理员!");
        }catch(Exception ex){
		    logger.error(ex.getStackTrace());
		    ex.printStackTrace();
            tReportLogDTO.setState(ENUM_REPORTLOG_STATE.EXCEPTION.code());
            tReportLogDTO.setDescription(ex.getMessage());
            tPayInfoQryResponseDTO.setPassCode(ENUM_RETURN_MSG.FAIL_INFO.code());
            tPayInfoQryResponseDTO.setPassMsg("查询请求失败，返回信息");
		}finally{
            //8.持久化报文
            try {
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
                //response.getWriter().print(JSON.toJSONString(tPayInfoQryResponseDTO));
                Map<String,String> tree = new HashMap<String,String>();
                tree.put("passCode", tPayInfoQryResponseDTO.getPassCode());
                tree.put("passMsg",tPayInfoQryResponseDTO.getPassMsg());
                tree.put("merchantCode", tPayInfoQryResponseDTO.getMerchantCode());
                tree.put("bizNo",tPayInfoQryResponseDTO.getBizNo());
                //元转分
                if ("".equals(tPayInfoQryResponseDTO.getPayAmount())||tPayInfoQryResponseDTO.getPayAmount()==null) {
                    BigDecimal tBigDecimal = new BigDecimal("0");
                    tPayInfoQryResponseDTO.setPayAmount(tBigDecimal);
                    tree.put("payAmount",tPayInfoQryResponseDTO.getPayAmount().toString());
                }else {
                    AmountTransUtil amountTransUtil = new AmountTransUtil();
                    String Amount = amountTransUtil.transAmount(tPayInfoQryResponseDTO.getPayAmount());
                    tree.put("payAmount",Amount);
                }
                tree.put("currency",tPayInfoQryResponseDTO.getCurrency());
                tree.put("payType",tPayInfoQryResponseDTO.getPayType());
                tree.put("payDate",tPayInfoQryResponseDTO.getPayDate());
                tree.put("returnCode",tPayInfoQryResponseDTO.getReturnCode());
                tree.put("returnMsg",tPayInfoQryResponseDTO.getReturnMsg());
                logger.info("----查询结果签名信息----");
                String tCompareSignMsg = "";
                MerchantSignInfo tMerchantSignInfo = merchantInfoFacadeService.getMerchantByCode(tPayInfoQryResponseDTO.getMerchantCode());
                if (!"".equals(tPayInfoQryResponseDTO.getMerchantCode())&&null!=tPayInfoQryResponseDTO.getMerchantCode()) {   //非空校验
                	 tCompareSignMsg = WechatSignUtil.encryMD5(tree, tMerchantSignInfo.getSignKey());  //签名MD5加密
				}else {
					tCompareSignMsg = tree.toString();  //签名MD5加密
				}
                
                String data = "";
                try {
                    String jsonPayInfoQry = JSONObject.toJSONString(tPayInfoQryResponseDTO);
                    logger.info("查询结果为："+jsonPayInfoQry);
                    data = SecurityUtil.aesEncrypt(jsonPayInfoQry,QueryPaymentContants.REPORT_ENCRY_KEY);  //报问体加密 AES固定秘钥
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Map<String,String> paramMap2 = new HashMap<String,String>();
                paramMap2.put("query_data", data);  //AES密文 json
                paramMap2.put("sign_msg", tCompareSignMsg);  //签名 md5 结果
                logger.info("----返回查询结果信息----"+paramMap2.toString());
                response.getWriter().print(JSON.toJSONString(paramMap2));// "query_data="+data+"&"+"sign_msg="+tCompareSignMsg
            } catch (IOException e) {
                logger.error(e.getStackTrace());
            }
        }
	}
	
	/**
	 * 获取请求IP地址
	 * @param request
	 * @return
	 */
	private String getRemortIP(HttpServletRequest request) {
		if (request.getHeader("x-forwarded-for") == null) {
			return request.getRemoteAddr();
		}
		return request.getHeader("x-forwarded-for");
	}
}
